<?php

define ("__LOAD_FROM_FILE", 0);
define ("__LOAD_FROM_MEM", 1);

class TDomXMLParser{

//----------------------------------------------------------------------------------------------------------------------

	var $convert = false;
	var $strtoupper=false;

//----------------------------------------------------------------------------------------------------------------------

	function ParseAttributes(&$atr){
		$res = array();
		$index = sizeof($atr);
		for($i=0; $i<$index; $i++){
			if($this->strtoupper==1)
			    $name=strtoupper($atr[$i]->name);
			else
				$name=$atr[$i]->name;
		    $res[$name] = $atr[$i]->value;
		    if ( $this->convert )
		        $res[$name] = iconv('UTF-8','WINDOWS-1251',$res[$name]);
		}
		return $res;
	}

//----------------------------------------------------------------------------------------------------------------------

	function Parse($value, $mode){
		global $os_type;
		$res = array();
		$data = array();

		if ( $mode == __LOAD_FROM_FILE ){
		    if (isset($os_type) && $os_type == "windows")
		        $dom = domxml_open_file($value[0] != "/" && $value[1] != ":" ? dirname($_SERVER["ORIG_PATH_TRANSLATED"])."/".$value : $value);
			else
			    $dom = domxml_open_file($value);
		}elseif ( $mode == __LOAD_FROM_MEM )
		    $dom = domxml_open_mem($value);

		if( $dom ){
			$root = $dom->document_element();
			$root_child = $root->child_nodes();
			$attr = $this->ParseAttributes($root->attributes());
			$res[0]['tag'] = $root->tagname;
			if($this->strtoupper==1)
			    $res[0]['tag']=strtoupper($res[0]['tag']);
			if ( sizeof($attr) > 0 ){
				$res[0]['attributes'] = $attr;
				if($this->strtoupper==1)
				    $res[0]['attributes']=strtoupper($res[0]['attributes']);
			}
			$data = $this->ParseRecursionNode($root_child);
			if ( sizeof($data['__nodes']) > 0 ) $res[0]['children'] = $data['__nodes'];
			if ( sizeof($data['__values']) > 0 ) $res[0]['value'] = $data['__values'];
		}else{
			$res = false;
		}
		return $res;
	}

//----------------------------------------------------------------------------------------------------------------------

	function ParseRecursionNode(&$achild){
		$res = array();
		$nvalues = array();
		$all = array();

		$k = -1;
		$flag = false;

		$index = sizeof($achild);
		for($i=0; $i<$index; $i++){
			$flag = false;
			//перебираем вершины
			if( $achild[$i]->type == XML_ELEMENT_NODE ){
				//смотрим атрибуты
				if ( $achild[$i]->has_attributes() ){
					if ( !$flag ){
						$k++;
						$flag = true;
					}
					$res[$k]['attributes'] = $this->ParseAttributes($achild[$i]->attributes());
				}
				//есть ли дочерние ветви
				if( $achild[$i]->has_child_nodes() ){
					$bchild = $achild[$i]->child_nodes();
					unset($NextNode);
					$NextNode = $this->ParseRecursionNode($bchild);

					if ($NextNode != NULL){
						if ( !$flag ){
							$k++;
							$flag = true;
						}
						if( sizeof( $NextNode['__nodes'] ) > 0 ) $res[$k]['children'] = $NextNode['__nodes'];
						if( sizeof( $NextNode['__values'] ) > 0 ) $res[$k]['value'] = $NextNode['__values'];
					}
				}
				$res[$k]['tag'] = $achild[$i]->tagname;
				if($this->strtoupper==1)$res[$k]['tag']=strtoupper($res[$k]['tag']);
			}

			//Cчитываем значение тега
			else if ( $achild[$i]->type == XML_TEXT_NODE  ){
				unset($node_value);
				$node_value = trim($achild[$i]->node_value());
				if( $node_value != '' ){
					if ( !$flag ){
						$k++;
						$flag = true;
					}

					$nvalues = $node_value;
					if ( $this->convert ) $nvalues = iconv('UTF-8','WINDOWS-1251',$nvalues);
				}
			}

			 //Cчитываем CDATA
			else if ( $achild[$i]->type == XML_CDATA_SECTION_NODE   ){
				unset($node_value);
				$node_value = trim($achild[$i]->node_value());
				if( $node_value != '' ){
					if ( !$flag ){
						$k++;
						$flag = true;
					}
					$nvalues = $node_value;
					if ( $this->convert ) $nvalues = iconv('UTF-8','WINDOWS-1251',$nvalues);
				}
			}
        }

		$all['__values'] = $nvalues;
		$all['__nodes'] = $res;

		return $all;
    }

//----------------------------------------------------------------------------------------------------------------------

	function Free(){
		unset($this);
	}

//----------------------------------------------------------------------------------------------------------------------

}

?>